// define

// 带 # 号的不是C语言语句，include 也不是关键字
#include <stdio.h>

// const double PI = 3.14159;

// define：定义宏
// define <name> <value>
// 在编译器开始编译之前，编译预处理程序会把程序中的名字换成值
// 是完全的文本替换
// PI 是宏的名字，3.14...是值
// 如果宏中有其他宏的名字, 也会被替换
// 如果宏的值超过一行, 最后一行之前的行末要加反斜杠'\'
// 宏的值后面出现的注释不会被当作宏的值的一部分
#define PI 3.14159
// 编译的时候使用 `gcc source.c --save-temps` 可以保存中间文件
// .c -> .i -> .s -> a.out

#define PI2 2 * PI  // pi * 2
#define PRT printf("%f\n", PI); \
            printf("%f\n", PI2)
            // 结尾不要加分号!

int main(int argc, char const *argv[])
{
    printf("%f\n", 2 * PI * 3.0);
    printf("%f\n", PI2 * 3.0);

    PRT;

    printf("%s:%d\n", __FILE__, __LINE__);
    printf("%s, %s\n", __DATE__, __TIME__);

    return 0;
}

// 没有值的宏
// #define _DEBUG
// 告诉编译器已经有这个宏了
// 这类宏是用于条件编译的, 后面有其他的编译预处理指令来检查\
// 这个宏是否已经被定义过了

// 预定义的宏
// __LINE__: 当前行在源代码中的行数
// __FILE__: 当前文件名
// __DATE__: 编译时的日期
// __TIME__: 编译时的时间
// __STDC__: 当要求程序严格遵循ANSIC标准时该标识符被赋值为1